package com.dnjn.happiness.auth.handler;

import com.alibaba.fastjson2.JSON;
import com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketResponse;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
import com.aliyun.tea.TeaException;
import com.dnjn.happiness.auth.config.DingTalkConfig;
import com.dnjn.happiness.common.core.constant.CacheConstants;
import com.dnjn.happiness.common.core.utils.StringUtils;
import com.dnjn.happiness.common.redis.service.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class DingTalkHandler {
    @Autowired
    private DingTalkConfig config;

    /**
     * 使用 Token 初始化账号Client
     *
     * @return Client
     * @throws Exception
     */
    public static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
    }


    public String getJsapiTicket(String accessToken) throws Exception {
        try {
            Object expireinObj = redisCache.getCacheObject(CacheConstants.DING_TALK_JSAPI_TICKET_EXPIREIN+config.getClientId());
            Long expirein = Long.valueOf(expireinObj.toString());
            if (Objects.nonNull(expirein)) {
                if (expirein > System.currentTimeMillis()) {
                    String jsapiTicket = redisCache.getCacheObject(CacheConstants.DING_TALK_JSAPI_TICKET+config.getClientId());
                    if (StringUtils.isNotBlank(jsapiTicket)) {
                        return jsapiTicket;
                    }
                }
            }
        } catch (Exception e) {
            log.warn(e.getMessage());
        }
        com.aliyun.dingtalkoauth2_1_0.Client client = DingTalkHandler.createClient();
        com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketHeaders createJsapiTicketHeaders = new com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketHeaders();
        createJsapiTicketHeaders.xAcsDingtalkAccessToken = accessToken;
        try {
            CreateJsapiTicketResponse resp = client.createJsapiTicketWithOptions(createJsapiTicketHeaders, new com.aliyun.teautil.models.RuntimeOptions());
            log.info("resp {}", JSON.toJSONString(resp));
            String jsapiTicket = resp.getBody().getJsapiTicket();
            int expireIn1 = (int) (resp.getBody().getExpireIn() * 1000 - 180); //过期时间

            Long deadLine = System.currentTimeMillis() + expireIn1 - 180;
            redisCache.setCacheObject(CacheConstants.DING_TALK_JSAPI_TICKET_EXPIREIN+config.getClientId(), deadLine.toString());
            redisCache.setCacheObject(CacheConstants.DING_TALK_JSAPI_TICKET+config.getClientId(), jsapiTicket, expireIn1, TimeUnit.SECONDS);
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }
        }
        return null;
    }

    @Autowired
    private RedisService redisCache;

    public String getAccessToken() throws Exception {
        try {
            Object expireinStr = redisCache.getCacheObject(CacheConstants.DING_TALK_ACCESS_TOKEN_EXPIREIN+config.getClientId());
            Long expirein = Long.valueOf(expireinStr.toString());
            log.info("load expireIn: {}", new Date(expirein));
            if (Objects.nonNull(expirein)) {
                if (expirein > System.currentTimeMillis()) {
                    String accessToken = redisCache.getCacheObject(CacheConstants.DING_TALK_ACCESS_TOKEN+config.getClientId());
                    if (StringUtils.isNotBlank(accessToken)) {
                        return accessToken;
                    }
                }
            }
        } catch (Exception e) {
            log.warn(e.getMessage());
        }

//        java.util.List<String> args = java.util.Arrays.asList(args_);
        com.aliyun.dingtalkoauth2_1_0.Client client = DingTalkHandler.createClient();
        com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
                .setAppKey(config.getClientId())
                .setAppSecret(config.getClientSecret());
        try {
            GetAccessTokenResponse resp = client.getAccessToken(getAccessTokenRequest);
            log.info("resp {}", JSON.toJSONString(resp));

            String accessToken = resp.getBody().getAccessToken();
            //expireIn Long jsapiTicket过期时间，单位秒。
            int expireInNew = resp.getBody().getExpireIn().intValue() * 1000; //过期时间
            Long deadLine = System.currentTimeMillis() + expireInNew - 180;
            log.info("set expireIn: {}", new Date(deadLine));
            redisCache.setCacheObject(CacheConstants.DING_TALK_ACCESS_TOKEN_EXPIREIN+config.getClientId(), String.valueOf(deadLine));
            redisCache.setCacheObject(CacheConstants.DING_TALK_ACCESS_TOKEN+config.getClientId(), accessToken, expireInNew, TimeUnit.SECONDS);
            return accessToken;
        } catch (TeaException err) {
            log.error(err.getMessage(), err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            log.error(err.getMessage(), err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }

        }
        return null;
    }
}
